package eiisan.security;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import eiisan.BlogManageApplication;
import eiisan.config.security.util.Matcher;
import eiisan.constant.enums.user.PermissionTypeEnum;
import eiisan.constant.settings.PropertyKey;
import eiisan.dao.domain.user.Permission;
import eiisan.dao.domain.user.Role;
import eiisan.security.service.InitPermissionRoleService;
import eiisan.util.common.EmptyUtil;
import eiisan.util.json.JSONUtil;
import eiisan.util.reflect.ReflectUtil;
import eiisan.util.spring.ContextUtil;
import eiisan.util.spring.PropertyUtil;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 根据所有controller初始化权限
 * @author gragonfly
 * @date 2019/7/8
 **/
@Configuration
public class InitPermissionMain {

    //steam flatMap和map的区别 参考https://www.cnblogs.com/yucy/p/10260014.html
    public static void main(String[] args) throws JsonProcessingException {
        SpringApplication.run(BlogManageApplication.class, args);
        InitPermissionRoleService initPermissionRoleService = ContextUtil.get(InitPermissionRoleService.class);

        List<Permission> permissionList = new ArrayList<>();
        Date date = new Date();

        //拿到mvc里定义的所有端点,然后自动生成权限
        //这里是从spring上下文里拿出所有HandlerMapping
        BeanFactoryUtils.beansOfTypeIncludingAncestors(ContextUtil.context(), HandlerMapping.class, true, false)
            .values().stream().filter((iter) -> {
                //过滤出其中的RequestMappingHandlerMapping
                return iter instanceof RequestMappingHandlerMapping;
            }).map((iter) -> {
                //取出所有的RequestMapping和对应的HandlerMethod,即@RequestMapping,@GetMapping,@PostMapping这些注解和它们所在的方法
                return ((RequestMappingHandlerMapping) iter).getHandlerMethods().entrySet();
            }).flatMap(Collection::stream)
            .forEach((entry) -> {
                //这里遍历map,map的类型是Entry<RequestMappingInfo, HandlerMethod>
                String requestUrl = PropertyUtil.get(PropertyKey.Web.BASE_PATH) + entry.getKey().getPatternsCondition()
                        .getPatterns().stream().findFirst().get();
                //只有需要验证的url才有权限
                if (!Matcher.needVerify(requestUrl)) {
                    return;
                }
                //把url的server.servlet.context-path以及它前面的部分去掉
                requestUrl = requestUrl.substring(PropertyUtil.get(PropertyKey.Web.BASE_PATH).length());
                //获得请求类型
                String requestType = entry.getKey().getMethodsCondition().getMethods().stream().map(RequestMethod::name)
                        .findFirst().orElse(PermissionTypeEnum.ALL.name());
                String permissionName = ReflectUtil.getShortMethodName(entry.getValue().getMethod());
                Permission permission = new Permission();
                permission.setCreateTime(date);
                permission.setUrl(requestUrl);
                permission.setName(permissionName);
                permission.setDescription(permissionName);
                if (requestType.equals("GET")) {
                    permission.setType(PermissionTypeEnum.GET.getVal());
                } else if (requestType.equals("POST")) {
                    permission.setType(PermissionTypeEnum.POST.getVal());
                } else if (requestType.equals("DELETE")) {
                    permission.setType(PermissionTypeEnum.DELETE.getVal());
                } else if (requestType.equals("PUT")) {
                    permission.setType(PermissionTypeEnum.PUT.getVal());
                } else {
                    permission.setType(PermissionTypeEnum.ALL.getVal());
                }
                permissionList.add(permission);
            });

        System.out.println("权限条目数量:" + permissionList.size());
        System.out.println("权限详细信息:");
        permissionList.forEach(p -> {
            try {
            System.out.println(JSONUtil.string(p));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        });
        List<Permission> permissions = initPermissionRoleService.saveNewPermissions(permissionList);
        SpringApplication.exit(ContextUtil.context(), () -> 1);
    }

}
